#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>

#define IOC_LTE_MAGIC  'G'
//#define LTEPW_ON	_IO(IOC_LTE_MAGIC, 0x58) //0b_0101_1000
//#define LTEPW_OFF	_IO(IOC_LTE_MAGIC, 0x51) //0b_0101_0001
//#define LTEWK_ON	_IO(IOC_LTE_MAGIC, 0x5f) //0b_0101_1111
//#define LTEWK_OFF	_IO(IOC_LTE_MAGIC, 0x25) //0b_0010_0101
//#define LTERS_ON	_IO(IOC_LTE_MAGIC, 0x43) //0b_0100_0011
//#define LTERS_OFF	_IO(IOC_LTE_MAGIC, 0x49) //0b_0100_1001

typedef enum lte_e {
    LTEPW_ON, LTEPW_OFF, LTEWK_ON, LTEWK_OFF, LTERS_ON, LTERS_OFF
} lte_e;
const int ltecode[] = {0x58, 0x51, 0x5f, 0x25, 0x43, 0x49};
const char *ltestr[] = {"LTEPW_ON", "LTEPW_OFF", "LTEWK_ON", "LTEWK_OFF", "LTERS_ON", "LTERS_OFF"};

typedef struct _ioctl_cmd_t {
    lte_e ioctl;
    int delay;
} ioctl_cmd_t;

ioctl_cmd_t pwr_off[] = {{LTEWK_ON, 1 + 3},
        //{LTEWK_OFF, 3},
                         {LTEWK_ON, 1},
                         {LTEPW_ON, 1}};
ioctl_cmd_t pwr_on[] = {{LTEWK_ON,  1},
                        {LTEPW_OFF, 2 + 2},
        //{LTEWK_OFF, 2},
                        {LTEWK_ON,  1},
                        {LTERS_ON,  1},
                        {LTERS_OFF, 1}};

static void ltepwr_ioctl(int fd, ioctl_cmd_t *pcmd) {
    int i, rc;

    fprintf(stdout, "ioctl=%s", ltestr[pcmd->ioctl]);
    fflush(stdout);

    rc = ioctl(fd, _IO(IOC_LTE_MAGIC, ltecode[pcmd->ioctl]), 0);
    fprintf(stdout, ", rc=%d", rc);
    fflush(stdout);

    for (i = 0; i < pcmd->delay; ++i) {
        sleep(1);

        fprintf(stdout, ".");
        fflush(stdout);
    }
    fprintf(stdout, "\n");
}

static void ltepwr_ioctl_group(int fd, ioctl_cmd_t cmds[], int n) {
    int i;

    for (i = 0; i < n; ++i) {
        ioctl_cmd_t *pcmd = &cmds[i];
        ltepwr_ioctl(fd, pcmd);
    }
}

int main(int argc, char *argv[]) {
    int i;

    if (argc < 3) {
        fprintf(stderr, "usage: %s -p --power 0[off] | 1[on]\n", argv[0]);
        return EXIT_FAILURE;
    }

    for (i = 1; i < argc; ++i) {
        if (0 == strcmp("-p", argv[i]) || 0 == strcmp("--power", argv[i])) {
            int fd = open("/dev/ltepw", O_RDWR);
            if (-1 == fd) {
                fprintf(stderr, "failed to open /dev/ltepw\n");
                return EXIT_FAILURE;
            }

            i++;
            if (0 == strcmp("0", argv[i]) || 0 == strcmp("off", argv[i])) {
                ltepwr_ioctl_group(fd, pwr_off, sizeof(pwr_off) / sizeof(ioctl_cmd_t));
            } else if (0 == strcmp("1", argv[i]) || 0 == strcmp("on", argv[i])) {
                ltepwr_ioctl_group(fd, pwr_on, sizeof(pwr_on) / sizeof(ioctl_cmd_t));
            }

            close(fd);
        }
    }

    sleep(5);

    return EXIT_SUCCESS;
}
